/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { DataGridColumn, DataGridProps } from '../data-grid.props';
import { Ref, ref } from 'vue';
import { UseDataRow, UseDataView, UseGroupRow, UseSummaryRow, UseVisualData, VisualData } from './types';

export function useVisualData(
    props: DataGridProps,
    columns: Ref<DataGridColumn[]>,
    dataViewComposition: UseDataView,
    visibleCapacity: Ref<number>,
    preloadCount: number,
    useDataRowComposition: UseDataRow,
    useGroupRowComposition: UseGroupRow,
    useSummaryRowComposition: UseSummaryRow
): UseVisualData {
    const maxVisibleRowIndex = ref(visibleCapacity.value - 1 + preloadCount);
    const minVisibleRowIndex = ref(0);
    const { renderDataRow } = useDataRowComposition;
    const { renderGroupRow } = useGroupRowComposition;
    const { renderSummaryRow } = useSummaryRowComposition;

    function getVisualDataRender(dataViewItem: any) {
        let visualDataRender = renderDataRow;
        if (dataViewItem.__fv_data_grid_group_row__) {
            visualDataRender = renderGroupRow;
        }
        if (dataViewItem.__fv_data_grid_group_summary__) {
            visualDataRender = renderSummaryRow;
        }
        return visualDataRender;
    }

    function getVisualData(start: number, end: number, pre?: any, forceToRefresh?: boolean): VisualData[] {
        const { dataView } = dataViewComposition;
        const visualDatas: VisualData[] = [];
        if (dataView.value.length > 0) {
            const refreshKey = forceToRefresh ? Date.now().toString() : '';
            for (let rowIndex = start, visualIndex = 0; rowIndex <= end; rowIndex++, visualIndex++) {
                const dataViewItem = dataView.value[rowIndex];
                const preDataItem = dataView.value[rowIndex - 1] || pre;
                const preRow = visualDatas[visualIndex - 1];
                const targetPosition = preDataItem ? (preDataItem.__fv_data_position__ || 0) + (preDataItem.__fv_data_height__ || 0) : 0;
                const renderCurrentRow = getVisualDataRender(dataViewItem);
                const currentRow = renderCurrentRow(dataViewItem, preDataItem, preRow, rowIndex, targetPosition, columns.value);
                currentRow.refreshKey = refreshKey;
                visualDatas.push(currentRow);
            }
        }
        minVisibleRowIndex.value = visualDatas.length > 0 ? visualDatas[0].index : 0;
        maxVisibleRowIndex.value = visualDatas.length > 0 ? visualDatas[visualDatas.length - 1].index : 0;
        return visualDatas;
    }

    function toggleGroupRow(status: 'collapse' | 'expand', groupRow: VisualData, visibleDatas: VisualData[]): VisualData[] {
        const groupField = groupRow.groupField || '';
        const { groupValue } = groupRow;
        dataViewComposition[status](groupField, groupValue);
        const { dataView } = dataViewComposition;
        const start = visibleDatas[0].index;
        const end = Math.min(start + visibleCapacity.value + preloadCount + 1, dataView.value.length - 1);
        const visualDatas: VisualData[] = getVisualData(start, end);
        return visualDatas;
    }

    return { getVisualData, maxVisibleRowIndex, minVisibleRowIndex, toggleGroupRow };
}
